# -*- encoding: utf-8 -*-

"""
------------------------------------------
@File       : 10.assignment_expression.py
@Author     : maixiaochai
@Email      : maixiaochai@outlook.com
@CreatedOn  : 2021/7/27 16:20
------------------------------------------
    赋值表达式(assignment expression)的使用
    作用：1）减少代码重复, 简化复杂结构
         2）压低 count变量的地位，使其只出现在 if语句块中

    海象操作符(walrus operator) :=
        1）为什么叫海象，顺时针旋转90度，冒号是海象的眼睛，等号是海象的牙
        2）效果，先赋值再计算

    PS: 海象和海豹长得很像，不过，海象有牙，海豹没牙
    Python ≥ 3.8.x

"""

fresh_fruit = {
    'apple': 10,
    'banana': 8,
    'lemon': 5
}


def make_lemonade(count):
    """制作柠檬水,柠檬汁"""
    print(f'Making {count} lemons into lemonade')


def make_cider(count):
    print(f'Making cider with {count} apples')


def out_of_stock():
    """缺货"""
    print('Out of stock!')


def lemonade():
    """
    顾客要柠檬水，就要先检查柠檬数据够不够，然后根据数据量执行下一步
    柠檬效力强，只需要一个就能做柠檬水
    普通版
    """
    count = fresh_fruit.get('lemon', 0)

    # 在Python中，数字0也是零值的一种，布尔值为false
    if count:
        make_lemonade(count)
    else:
        out_of_stock()


def lemonade_pro():
    """
        柠檬水，赋值表达式版
    """
    # 赋值表达式的应用，把 := 后面的结果计算出来，赋给count，然后 if再判断count是否为零值
    if count := fresh_fruit.get('lemon', 0):
        make_lemonade(count)
    else:
        out_of_stock()


def cider():
    """
        苹果汁-普通版
        4个以上苹果才能做苹果汁
    """
    count = fresh_fruit.get('banana', 0)

    if count > 4:
        make_cider(count)
    else:
        out_of_stock()


def cider_pro():
    """
        苹果汁-普通版
        4个以上苹果才能做苹果汁
    """

    # 注意这里的 括号，这里不是通过是否为零值判断，而是比较是否 >= 4个
    if (count := fresh_fruit.get('banana', 0)) >= 4:
        make_cider(count)
    else:
        out_of_stock()


class OutOfBananas(Exception):
    pass


def slice_bananas(count):
    print(f'Slicing {count} bananas')
    return count * 4


def make_smoothies(count):
    """
        制作冰沙
        smoothies, 冰沙
    """
    print(f'Making a smoothies with {count} banana slices')


def banana_smoothies():
    """
        制作香蕉冰沙, 非赋值表达式写法
    """
    pieces = 0
    count = fresh_fruit.get('banana', 0)
    if count >= 2:
        pieces = slice_bananas(count)

    try:
        make_smoothies(pieces)
    except OutOfBananas:
        out_of_stock()


def banana_smoothies_pro():
    pieces = 0
    if (count := fresh_fruit.get('banana', 0)) >= 2:
        pieces = slice_bananas(count)

    try:
        make_smoothies(pieces)
    except OutOfBananas:
        out_of_stock()


def auto_store():
    """
        按照一定的顺序，自动给客人制作饮品，这样就不用点餐了
        其实这里可以用 if ...elif ... elif ... else
    """
    count = fresh_fruit.get('banana', 0)
    if count >= 2:
        pieces = slice_bananas(count)
        make_smoothies(pieces)
    else:
        count = fresh_fruit.get('apple', 0)
        if count >= 4:
            make_cider(count)
        else:
            count = fresh_fruit.get('lemon', 0)
            if count:
                make_lemonade(count)
            else:
                print('Nothing')


def auto_store_pro():
    if (count := fresh_fruit.get('banana', 0)) >= 2:
        pieces = slice_bananas(count)
        make_smoothies(pieces)

    elif (count := fresh_fruit.get('apple', 0)) >= 4:
        make_cider(count)

    elif count := fresh_fruit.get('lemon', 0):
        make_lemonade(count)

    else:
        print('Nothing')


FRUIT_TO_PICK = [
    {'apple': 1, 'banana': 3},
    {'lemon': 2, 'lime': 5},
    {'orange': 3, 'melon': 2},
]


def pick_fruit():
    if FRUIT_TO_PICK:
        return FRUIT_TO_PICK.pop(0)
    else:
        return []


def make_juice(fruit, count):
    return [(fruit, count)]


def all_to_juice():
    """
        将所有水果榨成汁，装进瓶子里
    """
    bottles = []
    while fresh_fruit2 := pick_fruit():
        for fruit, count in fresh_fruit2.items():
            batch = make_juice(fruit, count)
            bottles.extend(batch)


def main():
    # lemonade_pro()
    # cider()
    # cider_pro()
    # auto_store()
    auto_store_pro()


if __name__ == '__main__':
    main()
